package com.blb.service.impl;

import com.blb.service.StudentService;
import org.omg.IOP.TransactionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class TransactionServiceImpl {

    @Autowired
    private StudentService studentService;

    public void testTrans1(){
        //没有外部事务，required会创建独立的新事务，相互不影响，外部方法异常不能影响新事务
        studentService.updateRequired(1,12);
        studentService.updateRequired(2,12);
        throw new RuntimeException();
    }

    public void testTrans2() {
        //没有外部事务，required会创建独立的新事务，相互不影响，事务出现异常不会影响其它事务
        studentService.updateRequired(1,11);
        studentService.updateRequiredException(2,11);
    }

    @Transactional
    public void testTrans3() {
        //有外部事务，required会合并到外部事务中，任何异常会导致全部回滚
        studentService.updateRequired(1,13);
        studentService.updateRequired(2,13);
        throw new RuntimeException();
    }

    @Transactional
    public void testTrans4() {
        //有外部事务，required会合并到外部事务中，任何异常会导致全部回滚
        studentService.updateRequired(1,14);
        studentService.updateRequiredException(2,14);
    }

    @Transactional
    public void testTrans5() {
        //有外部事务，required会合并到外部事务中，任何异常会导致全部回滚
        //异常被外部事务处理，内部事务出现过异常，还是回滚
        studentService.updateRequired(1,15);
        try {
            studentService.updateRequiredException(2, 15);
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }

    @Transactional
    public void testTrans6() {
        //和外部事务合并，外部事务抛异常，回滚
        studentService.updateRequired(1,16);
        //独立新事务，不受其它事务影响，正常执行
        studentService.updateRequiresNew(2,16);
        throw new RuntimeException();
    }

    @Transactional
    public void testTrans7() {
        //合并到外部事务，外部事务接收内部事务异常，回滚
        studentService.updateRequired(1,21);
        //新事务，不会影响，执行
        studentService.updateRequiresNew(2,21);
        //新事务，有异常，回滚
        studentService.updateRequiresNewException(3,21);
    }

    @Transactional
    public void testTrans8() {
        //合并到外部事务，外部事务处理了异常，不回滚
        studentService.updateRequired(1,13);
        //独立执行，成功
        studentService.updateRequiresNew(2,13);
        try {
            //独立执行，异常回滚
            studentService.updateRequiresNewException(3, 13);
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }

    @Transactional
    public void testTrans9() {
        //nested 外部事务会影响子事务，回滚
        studentService.updateNested(1,18);
        studentService.updateNested(2,18);
        throw new RuntimeException();
    }

    @Transactional
    public void testTrans10() {
        //外部事务接收到子事务的异常，导致所有子事务回滚
        studentService.updateNested(1,18);
        studentService.updateNestedException(2,18);
    }

    @Transactional
    public void testTrans11() {
        //合并，外部事务异常被处理，正常执行
        studentService.updateRequired(1,17);
        //正常
        studentService.updateNested(2,17);
        try {
            //自身子事务回滚
            studentService.updateNestedException(3, 17);
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }

    @Transactional
    public void testTrans12() {
        //外部有事务，就合并到外部事务
        studentService.updateSupports(1,19);
        studentService.updateSupports(2,19);
        throw new RuntimeException();
    }

    //外部无事务，就非事务执行
    public void testTrans13() {
        //内部没事务，正常执行
        studentService.updateSupports(1,19);
        //内部没事务，正常执行，异常不能回滚
        studentService.updateSupportsException(2,19);
    }

    @Transactional
    public void testTrans14() {
        //外部事务有异常，回滚
        studentService.updateRequired(1,27);
        //事务挂起，无异常，提交成功
        studentService.updateNotSupports(2,27);
        //事务挂起，有异常，提交成功
        studentService.updateNotSupportsException(3,27);
    }

    //外部有事务就抛异常
    @Transactional
    public void testTrans15() {
        studentService.updateNever(1,18);
    }

    //外部无事务就抛异常
//    @Transactional
    public void testTrans16() {
        studentService.updateMandatory(1,22);
    }
}
